/**
 * Created by hdt3213 on 16-8-23.
 */

var HOST = "gobang.finley.pw", PORT = 80;
var url = "http://" + HOST + ":" + String(PORT) + "/game";
var ws;

var token = '';
var user = Object(), partner = Object();

var actionHandlers = {
    'sign-up': handleRegister,
    'sign-in': handleLogin,
    'sign-out': handleSignOut,
    'reset-password': handleResetPassword
};

var socketHandlers = {
    'sign-in': null,
    'partner-changed': handleNewPartner,
    'partner-ready': handleReady,
    'game-start': handleGameStart,
    'new-step': handlePartnerNewStep,
    'retract-ask': handleRetractAsk,
    'retract-answer': handleRetractAnswer,
    'resign': handleResign
};

function encrypt(password) {
    var salt_head = 'Chain For Perls';
    var salt_end = 'Should we replace Perls for Pearls?';
    var code = salt_head + password + salt_end;
    for (var i = 0; i < 16; i++) {
        code = md5(code);
    }
    return code;
}

function clearUser() {
    user = Object();
    partner = Object();
    token = '';
}

// http base

function sendRequest(data) {
    $.post(url, data, handleResponse);
}

function handleResponse(data, status) {
    if (data.result == 'ok') {
        var action = data.action;
        if (actionHandlers[action] != null) {
            actionHandlers[action](data);
        }
    }
    else {
        console.log('During action ' + data.action + ', error occurs:' + data.result);
        $.alert('During action ' + data.action + ', error occurs:' + data.result);
    }
}

function login(username, password) {
    var data = {
        action: 'sign-in',
        username: username,
        password: encrypt(password)
    };
    user.username = username;
    sendRequest(data);
}


function handleLogin(data) {
    console.log('login success');
    token = data.token;
    user.success = data.success;
    user.failure = data.failure;
    user.score = data.score;
    user.ready = 0;

    ws = new WebSocket("ws://" + HOST + ":" + String(PORT) + "/push");
    ws.onopen = onopen;
    ws.onmessage = onmessage;
    
    showPartner();
}

// ws base

var onopen = function () {
    var data = {
        username: user.username,
        token: token
    };
    var request = $.toJSON(data);

    ws.send(request);


};

var onmessage = function (event) {
    var response = event.data;
    var data = jQuery.parseJSON(response);
    if (data['result'] == 'ok') {
        var action = data['action'];
        if (socketHandlers[action] != null) {
            socketHandlers[action](data);
        }
    }
    else {
        console.log('During action ' + data.action + ', error occurs:' + data.result);
    }
};

// user action

function register(username, password) {
    password = encrypt(password);
    var data = {
        action: 'sign-up',
        username: username,
        password: password
    };
    sendRequest(data);
}

function handleRegister(data) {
    $.alert("注册成功!");
}

function resetPassword(username, oldPassword, newPassword) {
    data = {
        action: 'reset-password',
        username: username,
        old_password: encrypt(oldPassword),
        new_password: encrypt(newPassword)
    };
    sendRequest(data);
}

function handleResetPassword(data) {
    $.alert("密码重设成功!")
}

function signOut() {
    data = {
        action: 'sign-out',
        username: user.username,
        token: token
    };
    sendRequest(data);
}

function handleSignOut(data) {
    clearUser();
    showBoard();
    $.modal(indexData);
}
// prepare action

function sendChangePartner() {
    data = {
        action: 'change-partner',
        username: user.username,
        token: token
    };
    sendRequest(data);
}

function handleNewPartner(data) {
    partner.name = data.partner;
    partner.success = data.success;
    partner.failure = data.failure;
    partner.score = data.score;
    partner.ready = 0;
    updatePartnerView();
}

function sendReady(ready) {
    data = {
        action: 'set-ready',
        username: user.username,
        token: token,
        ready: ready
    };
    sendRequest(data);
    user.ready = ready;
}

function handleReady(data) {
    partner.ready = Number(data.ready);
    if (partner.ready == 0) {
        setReadyView('partner', 0);
    }
    else {
        setReadyView('partner', 1);
    }
}

function handleGameStart(data) {
    user.role = Number(data.role);
    model.startGame();
    showBoard();
    status = 3; // online
}

function sendNewStep(step) {
    if (!step) {
        return false;
    }
    data = {
        action: 'new-step',
        username: user.username,
        token: token,
        x: step[0],
        y: step[1]
    };
    sendRequest(data);
}

function handlePartnerNewStep(data) {
    var x = Number(data.x), y = Number(data.y), winner = VACANT;
    var role = model.newStep(x, y);
    drawPiece(x, y, role);
    // winner judge
    winner = judge(model.getLastStep());
    if (winner == BLACK || winner == WHITE) {
        gameOver(winner);
    }
}

function sendRetractAsk() {
    if (!model.gameStarted || model.history.length == 0) {
        return false;
    }
    data = {
        action: 'retract-ask',
        username: user.username,
        token: token
    };
    sendRequest(data);
}

function handleRetractAsk(data) {
    partnerRetractAsk();
}

function sendRetractAnswer(permission) {
    var data = {
        action: 'retract-answer',
        username: user.username,
        token: token,
        permission: permission
    };
    sendRequest(data);
}

function handleRetractAnswer(data) {
    var permission = Number(data.permission);
    if (permission == 1) {
        var step = model.retract();
        erasePiece(step[0], step[1]);
    }
}

function sendResign() {
    var data = {
        action: 'resign',
        username: user.username,
        token: token
    };
    sendRequest(data);
    // clear game view
    model.clear();
    clearBoard();
    // setup partner view
    showPartner();
    partner.ready = 0;
    user.ready = 0;
    setReadyView('partner', 0);
    setReadyView('user', 0);
}

function handleResign(data) {
    // alertMsg('你胜利了');
    // clear game view
   gameOver(user.role);
}